package com.ithuameng.admin.app.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ithuameng.admin.app.system.dao.SequenceDataMapper;
import com.ithuameng.admin.app.system.model.SequenceData;
import com.ithuameng.admin.app.system.model.SequenceRule;
import com.ithuameng.admin.app.system.service.ISequenceDataService;
import com.ithuameng.admin.app.system.service.ISequenceRuleService;
import com.ithuameng.admin.enums.CommonError;
import com.ithuameng.admin.enums.SequenceType;
import com.ithuameng.admin.exception.AdminException;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;

/**
 * Sequence data service implementation
 *
 * @author ithuameng
 */
@Transactional
@Service
public class SequenceDataServiceImpl extends ServiceImpl<SequenceDataMapper, SequenceData> implements ISequenceDataService {

    private static final String SEQ_TPL_YEAR_FULL = "#YYYY#";

    private static final String SEQ_TPL_YEAR_SHORT = "#YY#";

    private static final String SEQ_TPL_YEAR_MONTH = "#MM#";

    private static final String SEQ_TPL_YEAR_DAY = "#DD#";

    @Resource
    private ISequenceRuleService sequenceRuleService;

    @Override
    public synchronized String getNextSeq(SequenceType type) {
        SequenceRule sequenceRule = sequenceRuleService.getSeqRuleByType(type);
        if (sequenceRule == null) {
            throw new AdminException(CommonError.BIZ_ERR, "流水号类型未定义");
        }
        int length = sequenceRule.getLength();
        String prefix = sequenceRule.getPrefix();
        String precode = prefix + handleSequencePattern(sequenceRule.getPattern());
        SequenceData sequenceData = this.getSeqDataByPre(prefix, precode);
        Long currentValue = 1L;
        if (sequenceData == null) {
            sequenceData = new SequenceData();
            sequenceData.setPrefix(prefix);
            sequenceData.setPrecode(precode);
            sequenceData.setCurrentVal(currentValue);
            super.save(sequenceData);
        } else {
            currentValue = sequenceData.getCurrentVal();
            currentValue++;
            sequenceData.setCurrentVal(currentValue);
            super.updateById(sequenceData);
        }
        return precode + getSeqNumber(currentValue, length);
    }

    @Override
    public SequenceData getSeqDataByPre(String prefix, String preCode) {
        QueryWrapper<SequenceData> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(SequenceData.PREFIX, prefix);
        if (StringUtils.isNotBlank(preCode)) {
            queryWrapper.eq(SequenceData.PRECODE, preCode);
        }
        List<SequenceData> seqDataList = super.list(queryWrapper);
        if (seqDataList.size() > 0) {
            return seqDataList.get(0);
        }
        return null;
    }

    private String handleSequencePattern(String pattern) {
        if (StringUtils.isBlank(pattern)) {
            return "";
        }
        ZonedDateTime now = ZonedDateTime.now();
        // 替换4位年，如有
        String seqPrefix = pattern.replace(SEQ_TPL_YEAR_FULL, now.format(DateTimeFormatter.ofPattern("yyyy")));
        // 替换2位年，如有
        seqPrefix = seqPrefix.replace(SEQ_TPL_YEAR_SHORT, now.format(DateTimeFormatter.ofPattern("yy")));
        // 替换2位月份，如有
        seqPrefix = seqPrefix.replace(SEQ_TPL_YEAR_MONTH, now.format(DateTimeFormatter.ofPattern("MM")));
        // 替换2位日，如有
        seqPrefix = seqPrefix.replace(SEQ_TPL_YEAR_DAY, now.format(DateTimeFormatter.ofPattern("dd")));
        return seqPrefix;
    }

    public String getSeqNumber(long currentValue, int length) {
        return StringUtils.leftPad(String.valueOf(currentValue), length, '0');
    }
}
